package com.jiubanqingchen.future.org.authority.role;

import com.jfinal.aop.Aop;
import com.jfinal.aop.Before;
import com.jfinal.kit.Kv;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.tx.Tx;
import com.jiubanqingchen.future.common.enums.WebSocketCategory;
import com.jiubanqingchen.future.common.tool.WebSocketTool;
import com.jiubanqingchen.future.model.models.ResourceAuthority;
import com.jiubanqingchen.future.model.models.Role;
import com.jiubanqingchen.future.model.models.User;
import com.jiubanqingchen.future.model.models.UserGroupRole;
import com.jiubanqingchen.future.org.admin.Json;
import com.jiubanqingchen.future.org.admin.ModelService;
import com.jiubanqingchen.future.org.annotation.Sqlkey;
import com.jiubanqingchen.future.org.authority.menu.MenuService;
import com.jiubanqingchen.future.org.authority.resourceAuthority.ResourceAuthorityService;
import com.jiubanqingchen.future.org.authority.user.UserAuthorityService;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Sqlkey("role.list")
public class RoleService extends ModelService<Role> {

    /**
     * 得到角色的菜单树
     *
     * @param kv
     * @return
     */
    public Record getRoleMenuTree(Kv kv) {
        MenuService menuService = Aop.get(MenuService.class);
        Record record = new Record();
        record.set("treeData", menuService.menuTree(kv));
        ResourceAuthorityService resourceAuthorityService = Aop.get(ResourceAuthorityService.class);
        record.set("checkedKeys", resourceAuthorityService.getResourceIdsByRoleId(kv.getStr("roleId")));
        return record;
    }

    /**
     * 更新角色权限信息
     *
     * @param record
     * @param _usr
     * @return
     * @throws Exception
     */
    @Before(Tx.class)
    public boolean updateRoleResourceAuthority(Record record, User _usr) throws Exception {
        String roleId = record.getStr("roleId");
        String resourceKey = record.getStr("resourceKeys");
        //删除之前存在的权限信息
        delete(getTableName(ResourceAuthority.class), "roleId", roleId, _usr);
        if (resourceKey == null) return false;
        String[] resourceKeys = resourceKey.split(",");
        ResourceAuthority resourceAuthority = null;
        List<ResourceAuthority> list = new ArrayList<>();
        for (String key : resourceKeys) {
            resourceAuthority = new ResourceAuthority();
            resourceAuthority.setResourceId(key).setRoleId(roleId).setResourceType("MENU");
            list.add(resourceAuthority);
        }
        //批量插入权限信息
        ResourceAuthorityService resourceAuthorityService = Aop.get(ResourceAuthorityService.class);
        resourceAuthorityService.insertBatch(list, null, _usr);
        afterUpdateRoleResourceAuthority(roleId);
        return true;
    }

    @Override
    public void afterDelete(Role role, Record record, User _usr) throws Exception {
        String roleId = role.getRoleId();
        //删除角色用户/部门关联信息
        delete(getTableName(UserGroupRole.class), "roleId", roleId, _usr);
        //删除角色权限信息
        delete(getTableName(ResourceAuthority.class), "roleId", roleId, _usr);
        //通知操作
        afterUpdateRoleResourceAuthority(roleId);
        super.afterDelete(role, record, _usr);
    }

    /**
     * 权限删除之后做缓存清理 与页面强制刷新操作
     *
     * @param roleId 角色id
     */
    private void afterUpdateRoleResourceAuthority(String roleId) throws IOException {
        //当前角色下用户信息不为空 则清理这些用户的权限菜单缓存
        String[] roleUserIds = getRoleUserIds(roleId);
        if (roleUserIds != null) {
            UserAuthorityService userAuthorityService = Aop.get(UserAuthorityService.class);
            userAuthorityService.removeAuthorityCaches(roleUserIds);
            //websocket通知客户端 系统强制刷新页面
            WebSocketTool.sendMessageTo(new Json(WebSocketCategory.AUTHORITY_CHANGE.getCode(), WebSocketCategory.AUTHORITY_CHANGE.getMsg()), roleUserIds);
        }
    }

    /**
     * 得到角色用户数组
     *
     * @param roleId
     * @return
     */
    private String[] getRoleUserIds(String roleId) {
        List<String> userIds = Db.query(Db.getSql("role.getRoleUserIds"), roleId, roleId);
        if (userIds.isEmpty()) return null;
        return userIds.toArray(new String[userIds.size()]);
    }
}